﻿using System;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Newtonsoft.Json;
using Volo.Abp;
using Volo.Abp.Validation;

namespace Yyd.Share
{
    public class HandleRuntimeErrors
    {
        private const string ErrorResponseType = "application/json";
        private const string CorsResponseHeader = "Access-Control-Allow-Origin";

        public static async Task Handle(HttpContext context)
        {
            var efh = context.Features.Get<IExceptionHandlerFeature>();
            if (efh != null)
            {
                await WriteErrorResponseAsync(context, efh.Error)
                    .ConfigureAwait(false);
            }
        }

        private static async Task WriteErrorResponseAsync(HttpContext context, Exception ex)
        {
            var wrapData = WrapData(context, ex);
            context.Response.StatusCode = StatusCodes.Status200OK;
            context.Response.ContentType = ErrorResponseType;
            context.Response.Headers.Add(CorsResponseHeader, "*");

            var setting = new JsonSerializerSettings
            {
                ContractResolver = new Newtonsoft.Json.Serialization.CamelCasePropertyNamesContractResolver()
            };

            await context.Response
                .WriteAsync(JsonConvert.SerializeObject(wrapData, Formatting.None, setting))
                .ConfigureAwait(false);
        }


        public static BaseResultModel WrapData(HttpContext context, Exception ex)
        {
            var logTemplate = "{AppName}";
            BaseResultModel baseResultModel;


            if (ex is AbpValidationException validationException)
            {
                //操作异常
                logTemplate = $"{logTemplate} {nameof(AbpValidationException)}:";
                baseResultModel = BaseResultModel.Failed(ReturnCode.ParamError, "请求参数错误！",
                    validationException.ValidationErrors);
            }
            /*else if (ex is DataNotExistsException _)
            {
                //操作异常
                logTemplate = $"{logTemplate} {nameof(DataNotExistsException)}:";
                baseResultModel = BaseResultModel.Failed((ex as DataNotExistsException).ErrorCode, ex.Message);
            }*/
            /*else if (ex is OperationException _)
            {
                //操作异常
                logTemplate = $"{logTemplate} {nameof(OperationException)}:";
                baseResultModel = BaseResultModel.Failed(ReturnCode.OperationError, ex.Message);
            }*/
            else if (ex is UserFriendlyException _)
            {
                //操作异常
                logTemplate = $"{logTemplate} {nameof(UserFriendlyException)}:";
                baseResultModel = BaseResultModel.Failed(ReturnCode.OperationError, ex.Message);
            }

            else if (ex is HttpProxyException)
            {
                //外部服务接口请求异常
                logTemplate = $"{logTemplate} {nameof(HttpProxyException)}:";
                baseResultModel = BaseResultModel.Failed(ReturnCode.OperationError, "外部服务请求异常:" + ex.Message);
            }
            else
            {
                logTemplate = $"{logTemplate} RuntimeException:";

                var env = context.RequestServices.GetService<IHostEnvironment>();
                if (env != null && string.Equals(env.EnvironmentName, "live", StringComparison.OrdinalIgnoreCase))
                {
                    baseResultModel = BaseResultModel.Failed(ReturnCode.Failure, "偶然性网络不稳定，请重试。");
                }
                else
                {
                    //其他异常
                    baseResultModel = BaseResultModel.Failed(ReturnCode.Failure,
                        $"处理失败 {ex.Message},{JsonConvert.SerializeObject(ex)}");
                }
            }

            return baseResultModel;
        }
    }
}